#include "StdAfx.h"
#include "FMConnection.h"
#include "ErrorCheck.h"

FMDBConnection::FMDBConnection(FMDBApplication* pOracleDB)
{
	Init(pOracleDB);
}

FMDBConnection::FMDBConnection( void )
{
	Init(nullptr);
}
FMDBConnection::~FMDBConnection(void)
{
	if (m_pOCIErr)
	{
		OCIHandleFree(m_pOCIErr,OCI_HTYPE_ERROR);	//free error handle
	}
}

//caller should decide if open a new connection before close the old one.
void FMDBConnection::Open()
{
	if(m_ConnectionStatus == csOpened)
	{
		return;
	}

	m_pSvcCtx = m_pOracleDB->CreateSession(m_pDiagValues, m_pDiagCodes, m_iDiagNum, m_stmtCache);
	if (m_pSvcCtx != nullptr)
	{
		m_ConnectionStatus = csOpened;
	}
}

void FMDBConnection::Close()
{
	m_pOracleDB->ReleaseSession(m_pSvcCtx);
	m_ConnectionStatus=csClosed;
}

void FMDBConnection::GetDBServerVersion(text* buff,ub4 BuffSize)
{	
	OCIServerVersion (m_pSvcCtx,m_pOCIErr,buff,BuffSize,OCI_HTYPE_SVCCTX);
}

void FMDBConnection::GetDBClientVersion(sword *verMajor,sword *verMinor,sword *verUpdate,sword *verPatch,sword *verPort)
{
	OCIClientVersion(verMajor,verMinor,verUpdate,verPatch,verPort);
}

void FMDBConnection::SetDiagnosticAttributes( TCHAR (*AttriValue)[64],ub4 *AttriCode,short AttriNumber )
{
	m_pDiagValues=AttriValue;
	m_pDiagCodes=AttriCode;
	m_iDiagNum=AttriNumber;
}

void FMDBConnection::Init( FMDBApplication* pOracleDB )
{
	m_pOracleDB = pOracleDB;
	m_pSvcCtx = NULL;
	m_stmtCache = -1;
	m_pDiagValues = NULL;
	m_pDiagCodes = NULL;
	m_iDiagNum = 0;
	m_ConnectionStatus = csClosed;

	if (pOracleDB)
	{
		m_pOCIErr = pOracleDB->GetOCIErrorHandle();
	}
	else
	{
		m_pOCIErr=nullptr;
	}
}

void FMDBConnection::Commit( ub4 Mode/*=OCI_DEFAULT*/ )
{
	CheckErr(m_pOCIErr,OCITransCommit(m_pSvcCtx,m_pOCIErr,Mode));

}

void FMDBConnection::Rollback( ub4 Mode/*=OCI_DEFAULT*/ )
{
	CheckErr(m_pOCIErr,OCITransRollback(m_pSvcCtx,m_pOCIErr,Mode));

}

//this function is to be improved, we need more flexible on transaction
void FMDBConnection::BeginTransaction( ub4 Mode/*=OCI_TRANS_NEW*/ )
{
	//When OCI_TRANS_NEW is specified, the timeout parameter indicates the number of seconds the transaction can be inactive before it is automatically terminated by the system.
	//CheckErr(m_pOCIErr,OCITransStart(m_pSvcCtx,m_pOCIErr,90,Mode));//todo:I set default timeout is 90s. later we should set this value to proper one

}
